const config = require('./config');
const fs = require('fs');
const exec = require('child_process').execSync;
const path = require('path');
const upload = require('./controllers/mathpix').upload;
const del = require('del');
const logger = require("./common/log").logger("schedule");

// 获取绝对路径
function absolutePath(_path) {
    return path.isAbsolute(_path) ? _path : path.join(__dirname, _path);
}
const resourcePath = absolutePath(config.imageRecognition.path.resource);
const tempPath = absolutePath(config.imageRecognition.path.temporarily);
const jsonPath = absolutePath(config.imageRecognition.path.json);

let zipFileLength = 0;
let concurrency = process.env.concurrency || config.imageRecognition.concurrency;

// 并发数不能超过100
if (concurrency > 100) {
    concurrency = 100;
}
const imageUpload = {
    total: 0,
    success: 0,
    fail: 0
};

// 根据并发数，zip文件数 设置图片上传的间隔时间
function setUploadDuration() {
    return parseInt(1000 * zipFileLength / concurrency);
}

// 读取文件夹的zip文件
function readDir(path) {
    return new Promise((resolve, reject) => {
        fs.readdir(path, (err, files) => {
            if (err) {
                return reject(err);
            }
            resolve(files);
        })
    });
}
// 解压文件夹
async function unzipDir(dir) {
    const files = await readDir(dir);
    const tasks = [];
    files.map(file => {
        if (!/.zip$/i.test(file)) {
            return;
        }
        zipFileLength++;
        tasks.push(new Promise((resolve, reject) => {
            let cmd = `unzip -o -j ${resourcePath}/${file} -d ${tempPath}/${path.parse(file).name}`;
            logger.info(`start unzip file ${file}:${cmd}`);
            try {
                exec(cmd);
            } catch (err) {
                logger.error('unzip file error:', file);
                return reject(err);
            }
            logger.info('unzip file ok:', file);
            resolve();
        }));

    });
    return new Promise((resolve, reject) => {
        Promise.all(tasks).then(() => {
            logger.info('unzip dir ok!');
            resolve();
        }).catch(err => {
            logger.err('unzip dir error', err);
            reject(err);
        });
    });
}
// 上传这个unzip文件夹
async function uploadDir(dir) {
    const files = await readDir(dir);
    const tasks = [];
    let time = 0;
    files.map(file => {
        if (!/.(gif|jpe?g|png)$/i.test(file)) {
            return;
        }
        let duration = setUploadDuration();
        tasks.push(new Promise(async(resolve, reject) => {
            setTimeout(async() => {
                let filePath = `${dir}/${file}`;
                logger.info(`start upload file:${filePath}`);
                imageUpload.total++;
                try {
                    const data = await upload(filePath);
                    // if (data.httpResponse.statusCode !== 200) {
                    //     logger.error(`upload file ${filePath} error:`, data.httpResponse.statusCode);
                    // }
                    resolve({[file]: !data.body ? {} : typeof data.body === 'object' ? data.body : JSON.parse(data.body)});
                    imageUpload.success++;
                    logger.info(`upload file ok: ${filePath}`);
                } catch (e) {
                    logger.error(`upload file ${filePath} error`, e);
                    imageUpload.fail++;
                    resolve({});
                }
            }, time);
        }));
        time += duration;
    });
    return new Promise((resolve, reject) => {
        Promise.all(tasks).then(values => {
            resolve(values);
        }).catch(err => {
            logger.error(err);
            reject(err);
        });
    });
}

(async() => {
    let startTime = +new Date;
    await unzipDir(resourcePath);
    const dirs = await readDir(tempPath);
    const tasks = [];
    dirs.map(dir => {
        dir = tempPath + '/' + dir;
        tasks.push(new Promise(async(resolve, reject) => {
            try {
                const data = await uploadDir(dir);
                resolve(data);
                fs.writeFileSync(`${jsonPath}/${path.parse(dir).name}.json`, typeof data === 'object' ? JSON.stringify(data) : data);
                del.sync(dir, {force: true});
            } catch (e) {
                logger.error('upload file error', e);
                reject(e);
            }
        }));
    });
    return new Promise((resolve, reject) => {
        Promise.all(tasks).then(values => {
            resolve(values);
            logger.info({
                total: imageUpload.total,
                success: imageUpload.success,
                failed: imageUpload.fail,
                concurrency: concurrency,
                costTime: `${parseInt((+new Date - startTime) / 1000, 10)}s`
            });
            del.sync(`${resourcePath}/**.zip`, {force: true});
            process.exit();
        }).catch(err => {
            console.log(err);
            reject(err);
        });
    });
})();


// readDir('./media/temporarily');
// unzipFile('v1.0.zip');

// schedule.scheduleJob(rule, () => { // 每分钟执行图片识别任务
//     recognise();
// });